package net.blogways.ordermgr.common.command.dbservice;

import com.asiainfo.bpc.utils.ToolFactory;
import net.blogways.ordermgr.util.Constants;
import net.blogways.ordermgr.util.DBTools;
import net.blogways.ordermgr.util.RescodeConstants;
import net.blogways.ordermgr.util.SeqGenerator;
import com.asiainfo.utils.Utils;
import org.apache.commons.chain.Command;
import org.apache.commons.chain.Context;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutionException;

/**
 * @author chenlong
 * Created on 2018/3/6
 */
@Component("common:paramCommand")
public class ParamCommand implements Command{

  private static final Logger log =  LoggerFactory.getLogger(ParamCommand.class);

  @Override
  public boolean execute(Context context) throws Exception {
    return false;
  }

  /**
   * TD_S_OPERATE参数查询.
   * @param context
   * @return
   * @throws Exception
   */
  public boolean prepare(Context context) throws Exception {

    SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    if (!context.containsKey("OPERATE_CODE")) {
      return Utils.returnFalse(context, RescodeConstants.OPERATE_CODE_IS_NULL, "common_miss_operate_code");
    }

    context.put("VOPERATE_CODE", context.get("OPERATE_CODE"));
    List list = ToolFactory.getInstance()
            .getSqlCodeService(Constants.DATABASE_CEN)
            .select(Constants.SEL_FROM_BY_PK, Constants.OPERATE_PARAMS_TABLE, context);

    log.debug("Query Static Operate Params Begin !");
    log.debug("SQL_REF: " + Constants.SEL_FROM_BY_PK);
    log.debug("TAB_NAME: " + Constants.OPERATE_PARAMS_TABLE);
    log.debug("PARAMS: " + context);

    log.debug("Result: " + list.toString());

    if (list.size() != 1) {
      log.debug("Query Operate Failed");
      return Utils.returnFalseResult(context, "0001", "静态参数获取失败");
    }

    List ret = new ArrayList();
    Map<String, Object> map = (Map<String, Object>) list.get(0);
    Map<String, Object> tmp = new HashMap<>();
    for (String key : map.keySet()) {
      if (map.get(key) instanceof Timestamp) {
        tmp.put(key, format.format(map.get(key)));
      } else {
        tmp.put(key, map.get(key));
      }
    }
    ret.add(tmp);
    return Utils.returnOk(context, ret);
  }

  /**
   * 生成8、16、18位主键流程
   *
   * @param context
   * @return
   */
  public boolean getTicket(Context context) {
    Long seqId = null;
    Calendar calendar;
    try {
      //主键名
      String stub = (String) context.get("stub");
      //主键位数
      String ruleDetail = (String) context.get("ruleDetail");
      if ("18".equals(ruleDetail)) {//18位主键
        log.debug("ruleDetail= {}", ruleDetail);
        seqId = SeqGenerator.getInstance().next(stub);
      } else {//8或16位
        calendar = Calendar.getInstance();
        //获取自增长序列
        Map result = (Map) ToolFactory.getInstance().getSqlCodeService("ticket")
                .select("GET_TICKET", "TD_S_TICKETS", new HashMap<String, Object>() {
                  {
                    put("VSTUB", stub);
                  }
                }).get(0);
        long id = (long) result.get("ID");
        String year = calendar.get(Calendar.YEAR) + "";
        if ("8".equals(ruleDetail)) {
          String prefix = year.substring(year.length() - 2);
          seqId = Long.valueOf(prefix + String.format("%0" + (Integer.parseInt(ruleDetail) - prefix.length()) + "d", id));
        } else if ("16".equals(ruleDetail)) {
          String month = "0" + (calendar.get(Calendar.MONTH) + 1);
          String prefix = year.substring(year.length() - 2) + month.substring(month.length() - 2);
          seqId = Long.valueOf(prefix + String.format("%0" + (Integer.parseInt(ruleDetail) - prefix.length()) + "d", id));
        }
      }
      context.put("seqId", seqId);
    } catch (Exception e) {
      log.error("can not get sequence: {}", e);
    }
    return Command.CONTINUE_PROCESSING;
  }

  public boolean selectOne(Context context) throws Exception {
    log.debug("selectOne begin:**********, context = {}", context);
    String dbRoute = null;
    if (null != context.get("Base")){
      Map base = (Map) context.get("Base");
      dbRoute = base.get("DATASOURCE") == null ? null : base.get("DATASOURCE").toString();
    }
    if (null == dbRoute && context.get("DATASOURCE") != null) {
      dbRoute = context.get("DATASOURCE").toString();
    }
    Map result = DBTools.selectOne(context.get("SQL_REF").toString(), context.get("TAB_NAME").toString(), dbRoute,
            DBTools.parameterize((Map<String, Object>) context.get("JSON"))
    );
    log.debug("result = {}", result);
    if ((int) result.get("resultSize") != 1) {
      return Utils.returnFalse(context, "0001", "common_expect_one_row");
    }
    context.put("resultOne", result.get("resultOne"));
    log.debug("selectOne end:**********, context = {}", context);
    return Utils.returnOkResult(context, "查询完成");

  }

  /**
   * 查询当前数据库时间.
   * @param context
   * @return
   * @throws Exception
   */
  public boolean queryCurrentTime(Context context) throws Exception {
    String now = null;
    try {
      now = DBTools.queryCurrentTime();
    } catch (ExecutionException e) {
      e.printStackTrace();
      return Utils.returnFalseResult(context, "0001", "查询数据库当前时间失败");
    }
    String finalNow = now;
    return Utils.returnOk(context, new HashMap() {
      {
        put("NOW", finalNow);
      }
    });
  }


}
